package gaboli.common.utils;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * Provides basic Range Pattern for Java. Example of usage:
 * import static gaboli.common.utils.Range.range;
 * ...
 * for (Integer i : range(1,10)
 * {
 *     //do something here....
 * }
 *
 * @author @author C. Burrell deltafront@gmail.com
 */
public class Range implements Iterable<Integer>
{
    private List<Integer> list;

    private Range( Integer lower, Integer upper, Integer step )
    {
        list = new LinkedList<Integer>();
       if ( upper < 0 )
       {
           //assume that we are walking backwards and the step is now a negative number
           if ( step > 0 )
           {
               step *=-1;
           }
           for ( int i =lower; i > upper; i += step )
           {
               Integer integer = new Integer( i );
               list.add( integer );
           }
       }
        else
       {
           for ( int i =lower; i < upper; i += step )
           {
               Integer integer = new Integer( i );
               list.add( integer );
           }
       }
    }
    /**
     * Rules:
     * * If lower is less than upper, then the step is implied to be 1.
     * * If lower is greater than upper, then the step is implied to be -1.
     * @param lower Lower limit of range, inclusive.
     * @param upper Upper limit of range, exclusive.
     * @since 2.0
     */
    public static Range range( Integer lower, Integer upper )
    {
        return range( lower, upper, 1 );
    }

    /**
     * Rules:
     *      * If lower is less than upper, then the step is as used.
     *      * If lower is greater than upper, and the step is a non-negative integer, then
     *          the negative step equivalent  will be used.
     * @param upper Upper limit of range, exclusive.
     * @param lower Lower limit of range, inclusive.
     * @param step Amount to increment <em>n</em> by from <em>lower</em> to <em>upper</em>.
     * @since 2.0
     */
    public static Range range( Integer lower, Integer upper, Integer step )
    {
        return new Range( lower,upper,step );
    }
    @Override
    public Iterator<Integer> iterator()
    {
        return list.iterator();
    }
}